home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / workbench / directoryopus4 / dopus4_src / library / gui.c < prev    next >
C/C++ Source or Header  |  2000-03-11  |  11KB  |  355 lines

  1. /*
  2.  
  3. Directory Opus 4
  4. Original GPL release version 4.12
  5. Copyright 1993-2000 Jonathan Potter
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. All users of Directory Opus 4 (including versions distributed
  22. under the GPL) are entitled to upgrade to the latest version of
  23. Directory Opus version 5 at a reduced price. Please see
  24. http://www.gpsoft.com.au for more information.
  25.  
  26. The release of Directory Opus 4 under the GPL in NO WAY affects
  27. the existing commercial status of Directory Opus 5.
  28.  
  29. */
  30.  
  31. #include "dopuslib.h"
  32.  
  33. #define isinside(x,y,x1,y1,x2,y2) (x>=x1 && x<=x2 && y>=y1 && y<=y2)
  34.  
  35. void ShowRMBGadName(struct RastPort *,struct RMBGadget *,int);
  36. void HighlightRMBGad(struct RastPort *,struct RMBGadget *,int);
  37. int makeusstring(char *,char *,int *,int);
  38.  
  39. __saveds DoAddGadgets(register struct Window *win __asm("a0"),
  40.     register struct Gadget *firstgad __asm("a1"),
  41.     register char **text __asm("a2"),
  42.     register int count __asm("d0"),
  43.     register int fg __asm("d1"),
  44.     register int bg __asm("d2"),
  45.     register int add __asm("d3"))
  46. {
  47.     int num=0,realcount=0,of,ob,a,x,y,b,c,up,xp,yp,bl,len,offset;
  48.     char buf[80];
  49.     struct RastPort *rp;
  50.     struct Gadget *gad;
  51.  
  52.     rp=win->RPort; gad=firstgad;
  53.     of=rp->FgPen; ob=rp->BgPen;
  54.     x=rp->Font->tf_XSize; y=rp->Font->tf_YSize; bl=rp->Font->tf_Baseline;
  55.  
  56.     while (gad && num<count) {
  57.         while (text && text[realcount] && text[realcount]!=(char *)-1 &&
  58.             !text[realcount][0]) ++realcount;
  59.         if (text && !text[realcount]) text=NULL;
  60.  
  61.         if (gad->GadgetType==GTYP_STRGADGET) {
  62.             Do3DStringBox(rp,
  63.                 gad->LeftEdge-(gad->MutualExclude*2),gad->TopEdge-gad->MutualExclude,
  64.                 gad->Width+(gad->MutualExclude*4),gad->Height+(gad->MutualExclude*2),
  65.                 fg,bg);
  66.         }
  67.         else if (gad->GadgetType==GTYP_PROPGADGET) {
  68.             Do3DBox(rp,
  69.                 gad->LeftEdge-2,gad->TopEdge-1,
  70.                 gad->Width+4,gad->Height+2,
  71.                 fg,bg);
  72.         }
  73.         else if (gad->MutualExclude==GAD_CYCLE) {
  74.             Do3DCycleBox(rp,
  75.                 gad->LeftEdge+2,gad->TopEdge+1,
  76.                 gad->Width-4,gad->Height-2,
  77.                 fg,bg);
  78.         }
  79.         else if (gad->MutualExclude==GAD_CHECK) {
  80.             Do3DBox(rp,
  81.                 gad->LeftEdge+2,gad->TopEdge+1,
  82.                 22,9,
  83.                 fg,bg);
  84.         }
  85.         else if (gad->MutualExclude!=GAD_NONE && gad->MutualExclude!=GAD_RADIO) {
  86.             Do3DBox(rp,
  87.                 gad->LeftEdge+2,gad->TopEdge+1,
  88.                 gad->Width-4,gad->Height-2,
  89.                 fg,bg);
  90.         }
  91.  
  92.         SetAPen(rp,of);
  93.         SetBPen(rp,ob);
  94.  
  95.         if (text && text[realcount] && text[realcount]!=(char *)-1 &&
  96.             text[realcount][0]) {
  97.             a=strlen(text[realcount]);
  98.             up=-1;
  99.             for (b=0,c=0;b<a;b++) {
  100.                 if (text[realcount][b]=='_' && up==-1) up=c;
  101.                 else buf[c++]=text[realcount][b];
  102.             }
  103.             buf[c]=0;
  104.             if (up>-1) --a;
  105.             len=TextLength(rp,text[realcount],a);
  106.  
  107.             if (gad->GadgetType==GTYP_STRGADGET ||
  108.                 (gad->GadgetType==GTYP_PROPGADGET && !(((struct PropInfo *)gad->SpecialInfo)->Flags&FREEHORIZ)) ||
  109.                 gad->MutualExclude==GAD_GLASS ||
  110.                 gad->MutualExclude==GAD_CYCLE) {
  111.  
  112.                 if (gad->GadgetType==GTYP_STRGADGET) offset=gad->MutualExclude;
  113.                 else offset=0;
  114.  
  115.                 xp=gad->LeftEdge-(offset*2)-(len+x);
  116.                 yp=gad->TopEdge+((gad->Height+(offset*2)-y)/2)+bl-offset;
  117.             }
  118.             else if (gad->GadgetType==GTYP_PROPGADGET) {
  119.                 xp=gad->LeftEdge+((gad->Width-len)/2);
  120.                 yp=gad->TopEdge-(y*2)+bl;
  121.             }
  122.             else {
  123.                 switch (gad->MutualExclude) {
  124.                     case GAD_CHECK:
  125.                         xp=gad->LeftEdge+36;
  126.                         break;
  127.                     case GAD_RADIO:
  128.                         xp=gad->LeftEdge+gad->Width+8;
  129.                         break;
  130.                     default:
  131.                         xp=gad->LeftEdge+((gad->Width-len)/2);
  132.                         break;
  133.                 }
  134.                 yp=gad->TopEdge+((((gad->MutualExclude==GAD_CHECK)?12:gad->Height)-y)/2)+bl;
  135.             }
  136.  
  137.             DoUScoreText(rp,buf,xp,yp,up);
  138.         }
  139.  
  140.         if (gad->GadgetType==GTYP_BOOLGADGET &&
  141.             gad->MutualExclude!=GAD_CHECK &&
  142.             gad->MutualExclude!=GAD_RADIO &&
  143.             gad->Activation&GACT_TOGGLESELECT &&
  144.             gad->Flags&GFLG_SELECTED) HiliteGad(gad,rp);
  145.  
  146.         gad=gad->NextGadget;
  147.         ++num;
  148.         ++realcount;
  149.     }
  150.     if (add) {
  151.         AddGList(win,firstgad,-1,realcount,NULL);
  152.         gad=firstgad;
  153.         for (a=0;a<realcount && gad;a++) {
  154.             if (gad->GadgetType!=GTYP_PROPGADGET) {
  155.                 if (gad->GadgetType==GTYP_STRGADGET ||
  156.                     gad->MutualExclude==GAD_RADIO ||
  157.                     (gad->GadgetType==GTYP_BOOLGADGET && gad->MutualExclude==GAD_CHECK &&
  158.                         gad->Activation&GACT_TOGGLESELECT && gad->Flags&GFLG_SELECTED))
  159.                         RefreshGList(gad,win,NULL,1);
  160.             }
  161.             gad=gad->NextGadget;
  162.         }
  163.     }
  164.     return(realcount);
  165. }
  166.  
  167. __saveds DoDoRMBGadget(register struct RMBGadget *gad __asm("a0"),
  168.     register struct Window *window __asm("a1"))
  169. {
  170.     ULONG class;
  171.     USHORT code;
  172.     BOOL inside;
  173.     struct RastPort *rp;
  174.     int x,y,x1,y1,ret=-1;
  175.     ULONG idcmpflags,windowflags;
  176.     struct IntuiMessage *Msg;
  177.     struct Gadget dummy_gadget;
  178.  
  179.     x=window->MouseX; y=window->MouseY;
  180.     while (gad) {
  181.         if (gad->w>0 && gad->h>0) {
  182.             x1=gad->x+gad->w-1; y1=gad->y+gad->h-1;
  183.             if (isinside(x,y,gad->x,gad->y,x1,y1)) break;
  184.         }
  185.         gad=gad->next;
  186.     }
  187.     if (!gad) return(-1);
  188.     rp=window->RPort;
  189.  
  190.     idcmpflags=window->IDCMPFlags;
  191.     ModifyIDCMP(window,IDCMP_MOUSEBUTTONS|IDCMP_MOUSEMOVE|IDCMP_INACTIVEWINDOW);
  192.  
  193.     windowflags=window->Flags;
  194.     window->Flags|=WFLG_REPORTMOUSE;
  195.  
  196.     if (isinside(x,y,gad->x,gad->y,x1,y1)) {
  197.         if (gad->flags&RGF_ALTTEXT) ShowRMBGadName(rp,gad,1);
  198.         HighlightRMBGad(rp,gad,1);
  199.         inside=TRUE;
  200.     }
  201.     else inside=FALSE;
  202.  
  203.     dummy_gadget.LeftEdge=0;
  204.     dummy_gadget.TopEdge=0;
  205.     dummy_gadget.Width=window->Width;
  206.     dummy_gadget.Height=window->Height;
  207.     dummy_gadget.Flags=GFLG_GADGHNONE;
  208.     dummy_gadget.Activation=GACT_IMMEDIATE;
  209.     dummy_gadget.GadgetType=GTYP_BOOLGADGET;
  210.     dummy_gadget.GadgetRender=NULL;
  211.     dummy_gadget.SelectRender=NULL;
  212.     dummy_gadget.GadgetText=NULL;
  213.     AddGList(window,&dummy_gadget,0,1,NULL);
  214.  
  215.     FOREVER {
  216.         while (Msg=(struct IntuiMessage *)GetMsg(window->UserPort)) {
  217.             class=Msg->Class;
  218.             code=Msg->Code;
  219.             x=Msg->MouseX;
  220.             y=Msg->MouseY;
  221.             ReplyMsg((struct Message *)Msg);
  222.  
  223.             if (class==IDCMP_INACTIVEWINDOW) goto end_rmb;
  224.             if (class==IDCMP_MOUSEBUTTONS && code==MENUUP) {
  225.                 if (inside) ret=gad->id;
  226.                 goto end_rmb;
  227.             }
  228.             if (class==IDCMP_MOUSEMOVE) {
  229.                 if (!(isinside(x,y,gad->x,gad->y,x1,y1))) {
  230.                     if (inside) {
  231.                         HighlightRMBGad(rp,gad,0);
  232.                         if (gad->flags&RGF_ALTTEXT) ShowRMBGadName(rp,gad,0);
  233.                         inside=FALSE;
  234.                     }
  235.                 }
  236.                 else {
  237.                     if (!inside) {
  238.                         if (gad->flags&RGF_ALTTEXT) ShowRMBGadName(rp,gad,1);
  239.                         HighlightRMBGad(rp,gad,1);
  240.                         inside=TRUE;
  241.                     }
  242.                 }
  243.             }
  244.         }
  245.         Wait(1<<window->UserPort->mp_SigBit);
  246.     }
  247. end_rmb:
  248.     if (inside) {
  249.         HighlightRMBGad(rp,gad,0);
  250.         if (gad->flags&RGF_ALTTEXT) ShowRMBGadName(rp,gad,0);
  251.     }
  252.     RemoveGList(window,&dummy_gadget,1);
  253.     ModifyIDCMP(window,idcmpflags);
  254.     window->Flags=windowflags;
  255.     return(ret);
  256. }
  257.  
  258. void ShowRMBGadName(rp,gad,a)
  259. struct RastPort *rp;
  260. struct RMBGadget *gad;
  261. int a;
  262. {
  263.     struct RMBGadgetText *text;
  264.     int len,l,uspos,old;
  265.     char buf[100];
  266.  
  267.     if ((text=&gad->txt[a])) {
  268.         old=rp->DrawMode;
  269.         SetDrMd(rp,JAM2);
  270.         SetAPen(rp,text->bg);
  271.         RectFill(rp,gad->x+text->x,gad->y+text->y,gad->x+text->x+text->w-1,gad->y+text->y+text->h-1);
  272.         SetAPen(rp,text->fg);
  273.         SetBPen(rp,text->bg);
  274.         if (text->text) {
  275.             len=makeusstring(text->text,buf,&uspos,99);
  276.             while ((l=TextLength(rp,buf,len))>text->w) {
  277.                 if ((--len)==0) break;
  278.             }
  279.             buf[len]=0;
  280.             UScoreText(rp,buf,gad->x+text->x+((text->w-l)/2),
  281.                 gad->y+text->y+((text->h-rp->Font->tf_YSize)/2)+rp->Font->tf_Baseline,uspos);
  282.         }
  283.         SetDrMd(rp,old);
  284.     }
  285. }
  286.  
  287. void HighlightRMBGad(rp,gad,state)
  288. struct RastPort *rp;
  289. struct RMBGadget *gad;
  290. int state;
  291. {
  292.     if (gad->flags&RGF_ALTBORD) DrawBorder(rp,gad->high_bord[state],gad->x,gad->y);
  293.     else {
  294.         int old;
  295.  
  296.         old=rp->DrawMode;
  297.         SetDrMd(rp,COMPLEMENT);
  298.         RectFill(rp,gad->x,gad->y,gad->x+gad->w-1,gad->y+gad->h-1);
  299.         SetDrMd(rp,old);
  300.     }
  301. }
  302.  
  303. makeusstring(from,to,uspos,size)
  304. char *from,*to;
  305. int *uspos,size;
  306. {
  307.     int len,c;
  308.  
  309.     *uspos=-1;
  310.     for (c=0,len=0;len<size;c++) {
  311.         if (!from[c]) break;
  312.         else if (from[c]=='_' && *uspos==-1) *uspos=len;
  313.         else to[len++]=from[c];
  314.     }
  315.     to[len]=0;
  316.     return(len);
  317. }
  318.  
  319. void __saveds DoDoCycleGadget(register struct Gadget *gad __asm("a0"),
  320.     register struct Window *window __asm("a1"),
  321.     register char **choices __asm("a2"),
  322.     register int select __asm("d0"))
  323. {
  324.     int op,a;
  325.     struct RastPort *rp;
  326.  
  327.     rp=window->RPort;
  328.     op=rp->FgPen;
  329.     SetAPen(rp,rp->BgPen);
  330.     RectFill(rp,gad->LeftEdge+22,gad->TopEdge+1,
  331.         gad->LeftEdge+gad->Width-3,gad->TopEdge+gad->Height-2);
  332.     SetAPen(rp,op);
  333.     if (choices && choices[select]) {
  334.         Move(rp,gad->LeftEdge+20+((gad->Width-22-((a=strlen(choices[select]))*rp->Font->tf_XSize))/2),
  335.             gad->TopEdge+rp->Font->tf_Baseline+((gad->Height-rp->Font->tf_YSize)/2));
  336.         Text(rp,choices[select],a);
  337.     }
  338. }
  339.  
  340. void __saveds DoUScoreText(register struct RastPort *rp __asm("a0"),
  341.     register char *buf __asm("a1"),
  342.     register int xp __asm("d0"),
  343.     register int yp __asm("d1"),
  344.     register int up __asm("d2"))
  345. {
  346.     int a,x;
  347.  
  348.     Move(rp,xp,yp); Text(rp,buf,(a=strlen(buf)));
  349.     if (up>-1 && up<a) {
  350.         x=TextLength(rp,buf,up);
  351.         Move(rp,xp+x,yp+2);
  352.         Draw(rp,rp->cp_x+(TextLength(rp,&buf[up],1))-1,rp->cp_y);
  353.     }
  354. }
  355.